package sg.com.techstudio.ecc.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.generic.DateTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import sg.com.techstudio.ecc.email.GenericHTMLPreparator;
import sg.com.techstudio.ecc.filter.RegisterFilter;
import sg.com.techstudio.ecc.obj.LearningJourneyObj;
import sg.com.techstudio.ecc.obj.ParticipantObj;
import sg.com.techstudio.ecc.obj.RegisterObj;
import sg.com.techstudio.ecc.obj.SessionObj;
import sg.com.techstudio.ecc.util.NumberToolSg;

@Component("emailDao")
public class EmailDao {
	private static final Log log = LogFactory.getLog(EmailDao.class);
	@Autowired
	private VelocityEngine velocityEngine;
	
	@Autowired
	private JavaMailSender mailSender;
	
	@Autowired
	private EmailConfig confirmationEmailConfig, learningJourneyEmailConfig;
	
	@Autowired
	private SystemConfigDao systemConfigDao;
	
	public boolean sendConfirmationEmail(List<RegisterObj> registerList
			, RegisterFilter rf, boolean participantMode){
		if(registerList==null || registerList.isEmpty() || rf==null)
			return false;
		log.debug("sendConfirmationEmail() entry: regId:"+rf.getId()+"; partId"+rf.getParticipantId());
		for(RegisterObj r: registerList) {
			log.debug("sendConfirmationEmail() comparing "+r.getId()+" with "+rf.getId());
			if(r.getId().compareTo(rf.getId())==0) {
				log.debug("sendConfirmationEmail() found matched reg id: "+r.getId());
				if(participantMode) {
					if(r.countParticipants()<=0)
						return false;
					for(ParticipantObj p: r.getParticipantList())
						if(p.getId().compareTo(rf.getParticipantId())==0) {
							log.debug("sendConfirmationEmail() sending email to participant: "+p.getEmail());
							return sendConfirmationEmail(r, p);
						}
				} else {
					log.debug("sendConfirmationEmail() sending email to main reg:"+r.getEmail());
					return sendConfirmationEmail(r, false);
				}
			}
		}
		return false;
	}
	
	public boolean sendConfirmationEmail(RegisterObj r){
		return sendConfirmationEmail(r, true);
	}
	
	public boolean sendConfirmationEmail(RegisterObj r, boolean sendToParticipant){
		Map<String, Object> emailInfoMap = new HashMap<String, Object>();
		GenericHTMLPreparator emailPrep = null;
		if(r.getRegType()==1) {
			emailPrep = learningJourneyEmailPrep(r);
			List<LearningJourneyObj> ljList = systemConfigDao.learningJourneyList();
			for(LearningJourneyObj lj: ljList)
				if(r.getLearningJourney()==lj.getId().intValue())
					emailInfoMap.put("lj", lj);
		} else {
			emailPrep = confirmationEmailPrep(r);
			List<SessionObj> sesList = systemConfigDao.sessionList();
			for(SessionObj s:sesList) {
				if(s.getType()==1 && s.getNo()==r.getSessionA())
					emailInfoMap.put("s1", s);
				else if (s.getType()==2 && s.getNo()==r.getSessionB())
					emailInfoMap.put("s2", s);
				else if (s.getType()==3 && s.getNo()==r.getSessionC())
					emailInfoMap.put("s3", s);
				else if (s.getType()==4 && s.getNo()==r.getSessionD())
					emailInfoMap.put("s4", s);
			}
		}

		emailInfoMap.put("r", r);
		emailInfoMap.put("number", new NumberToolSg());
		emailInfoMap.put("datetool", new DateTool());
		emailPrep.setModel(emailInfoMap);
		mailSender.send(emailPrep);
		
		if(sendToParticipant && r.getRegType()!=1 && r.getParticipantCount()>0)
			for(ParticipantObj p: r.getParticipantList())
				sendConfirmationEmail(r, p);		
		return true;
	}
	
	public boolean sendConfirmationEmail(RegisterObj r, ParticipantObj p){
		GenericHTMLPreparator emailPrep = confirmationEmailPrep(p);
		Map<String, Object> emailInfoMap = new HashMap<String, Object>();
		List<SessionObj> sesList = systemConfigDao.sessionList();
		for(SessionObj s:sesList) {
			if(s.getType()==1 && s.getNo()==p.getSessionA())
				emailInfoMap.put("s1", s);
			else if (s.getType()==2 && s.getNo()==p.getSessionB())
				emailInfoMap.put("s2", s);
			else if (s.getType()==3 && s.getNo()==p.getSessionC())
				emailInfoMap.put("s3", s);
			else if (s.getType()==4 && s.getNo()==p.getSessionD())
				emailInfoMap.put("s4", s);
		}
		
		emailInfoMap.put("p", p);
		emailInfoMap.put("r", r);
		emailInfoMap.put("number", new NumberToolSg());
		emailInfoMap.put("datetool", new DateTool());
		emailPrep.setModel(emailInfoMap);
		mailSender.send(emailPrep);
		return true;
	}
	
	public boolean sendEmail(RegisterObj registerObj){
		log.debug("sendEmail() entry");
		return sendConfirmationEmail(registerObj);
	}
	
	protected GenericHTMLPreparator confirmationEmailPrep(RegisterObj r) {
		GenericHTMLPreparator emailPrep = new GenericHTMLPreparator();
		emailPrep.setVelocityEngine(velocityEngine);
		emailPrep.setFrom(confirmationEmailConfig.getFrom());
		emailPrep.setTo(r.getEmail());
//		emailPrep.setTo(TEST_EMAIL);
//		emailPrep.setCc(TEST_EMAIL_CC);
		emailPrep.setBcc(confirmationEmailConfig.getBcc());
		emailPrep.setSubject(confirmationEmailConfig.getSubject());
		emailPrep.setSenderName(confirmationEmailConfig.getSenderName());
		emailPrep.setTemplateLocation(confirmationEmailConfig.getTemplateLocation());
		return emailPrep;
	}
	
	protected GenericHTMLPreparator confirmationEmailPrep(ParticipantObj p) {
		GenericHTMLPreparator emailPrep = new GenericHTMLPreparator();
		emailPrep.setVelocityEngine(velocityEngine);
		emailPrep.setFrom(confirmationEmailConfig.getFrom());
		emailPrep.setTo(p.getEmail());
//		emailPrep.setTo(TEST_EMAIL);
//		emailPrep.setCc(TEST_EMAIL_CC);
		emailPrep.setBcc(confirmationEmailConfig.getBcc());
		emailPrep.setSubject(confirmationEmailConfig.getSubject());
		emailPrep.setSenderName(confirmationEmailConfig.getSenderName());
		emailPrep.setTemplateLocation(confirmationEmailConfig.getTemplateLocation());
		return emailPrep;
	}
	
	protected GenericHTMLPreparator learningJourneyEmailPrep(RegisterObj r) {
		GenericHTMLPreparator emailPrep = new GenericHTMLPreparator();
		emailPrep.setVelocityEngine(velocityEngine);
		emailPrep.setFrom(learningJourneyEmailConfig.getFrom());
		emailPrep.setTo(r.getEmail());
//		emailPrep.setTo(TEST_EMAIL);
//		emailPrep.setCc(TEST_EMAIL_CC);
		emailPrep.setBcc(learningJourneyEmailConfig.getBcc());
		emailPrep.setSubject(learningJourneyEmailConfig.getSubject());
		emailPrep.setSenderName(learningJourneyEmailConfig.getSenderName());
		emailPrep.setTemplateLocation(learningJourneyEmailConfig.getTemplateLocation());
		return emailPrep;
	}
	
	
	//for sending email manually
	
	protected static final String TEST_EMAIL = "dhany@techstudio.com.sg";
	protected static final String TEST_EMAIL_CC = "fauzi@techstudio.com.sg";
	private static EmailDao emailDao;
	private static String configLocation = "config/servlet-context.xml";
	public static void main(String[] args) {
		System.out.println("start");
		try {
			if(args!=null && args.length>=1)
				configLocation = args[0];
			initProcess(configLocation);
//			RegisterObj r = registrationDao.getRegisterObj(1);
			
//			emailDao.sendParticipantEmail(getP(), getR());
//			emailDao.sendOtherCompanyEmail(getR());
//			emailDao.sendChequeEmail(getR());
			emailDao.sendConfirmationEmail(getR());
		} catch (Exception e) {
			e.printStackTrace();
			log.error("EMailDao", e);
		}
		System.out.println("end");
	}
	
	protected static RegisterObj getR() {
		RegisterObj r = new RegisterObj();
		r.setId(1009L);
		r.setEmail(TEST_EMAIL);
		r.setName("main registratnt person");
		r.setNric("s1234567a");
		r.setSessionA(2);
		r.setSessionB(4);
		r.setSessionC(6);
		r.setSessionD(11);
		r.setLearningJourney(1);
//		r.setRegType(1);
//		r.setDietary("");
		//r.setDietary("vegetarian");
		r.getParticipantList().add(getP());
		return r;
	}
	
	protected static ParticipantObj getP() {
		ParticipantObj p = new ParticipantObj();
		p.setEmail(TEST_EMAIL);
		p.setName("participant name");
		p.setNric("s7654321a");
		p.setSessionA(3);
		p.setSessionB(1);
		p.setSessionC(8);
		p.setSessionD(10);
		return p;
	}
	
	@SuppressWarnings("resource")
	protected static void initProcess(String configLocation) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation);
		emailDao = ctx.getBean(EmailDao.class);
	}
}
